import os
import platform
import re
import shutil
import warnings

from  PyInstaller.__main__ import run
import sys
def file_walk_through(path, ext):
    """
    递归获取路径中指定扩展名的文件路径
    :param path: 路径
    :param ext: 扩展名或者全部扩展名的list
    :return: 文件路径
    """
    L_path = []
    L_road = []
    # 用来在函数中判断是db还是xls
    print("遍历路径：%s下所有：%s扩展名文件" % (path, ext))
    for root, dirs, files in os.walk(path):  # 遍历文件
        for file in files:
            if isinstance(ext, str):
                if os.path.splitext(file)[1] == ext or os.path.splitext(file)[1][1:] == ext:
                    L_path.append(re.sub(r'[\\/]', ".", os.path.join(root,file)))
            elif isinstance(ext, list):
                if os.path.splitext(file)[1] in ext or os.path.splitext(file)[1][1:] in ext:
                    L_path.append(re.sub(r'[\\/]', ".", os.path.join(root,file)))
    return L_path
def doPackFun_CMD(entry_file,add_data:str="",spec:bool=False):
    """
    将python程序打包为可执行exe文件(废弃方法)
    :param entry_file: 入口py文件
    :param add_data: 添加额外打包文件路径
    :param spec: 是否spec方式，需要根目录下存在同名spec文件
    :return:
    """
    warnings.warn("该方法由于调用系统CMD，对系统依赖性过高，已废弃",DeprecationWarning, stacklevel=2)
    def removeFolders(folders:str):
        for folder in folders:
            if os.path.isdir(folder) and os.path.exists(folder):
                shutil.rmtree(folder)
    removeFolders(["build","dist"])
    nowpath=os.path.abspath(".")
    disk=os.path.splitdrive(nowpath)[0]
    cmdpath=os.path.join(os.environ["SystemRoot"],"System32","cmd.exe")
    conda_name=os.path.split(sys.exec_prefix)[1]
    entry_file=os.path.abspath(entry_file)
    entry_file_name=os.path.split(entry_file)[1]
    entry_file_name_no_ext=os.path.splitext(entry_file_name)[0]
    spec_file=os.path.join(nowpath,entry_file_name_no_ext+".spec")
    if spec:
        if os.path.exists(spec_file):
            cmd_total="{} /c {}&&cd {}&&{}&&{}" \
                .format(cmdpath,
                        disk,
                        nowpath,
                        "activate %s"%conda_name,
                        "pyinstaller %s"%(spec_file))

        else:
            raise Exception(spec_file+"文件不存在，无法打包")
    else:
        if add_data=="":
            cmd_total="{} /c {}&&cd {}&&{}&&{}" \
                .format(cmdpath,
                        disk,
                        nowpath,
                        "activate %s"%conda_name,
                        "pyinstaller -F %s -p %s"%(entry_file,nowpath))
        else:
            cmd_total="{} /c {}&&cd {}&&{}&&{}" \
                .format(cmdpath,
                        disk,
                        nowpath,
                        "activate %s"%conda_name,
                        "pyinstaller -F %s -p %s --add-data %s"%(entry_file,nowpath,add_data))

    os.system(cmd_total)
    # print("打包文件已保存到：%s"%os.path.join(nowpath,"dist","%s.exe"%entry_file_name_no_ext))
def doPackFun(entry_file,add_data:str="",hidden_import:list=[],spec:bool=False,remove:bool=True):
    """
    将python程序打包为可执行exe文件
    :param entry_file: 入口py文件
    :param add_data: 添加额外打包文件路径
    :param spec: 是否spec方式，需要根目录下存在同名spec文件
    :return:
    """
    def removeFolders(folders:str):
        for folder in folders:
            if os.path.isdir(folder) and os.path.exists(folder):
                shutil.rmtree(folder)
    nowpath=os.path.abspath(".")
    entry_file=os.path.abspath(entry_file)
    entry_file_name=os.path.split(entry_file)[1]
    entry_file_name_no_ext=os.path.splitext(entry_file_name)[0]
    spec_file=os.path.join(nowpath,entry_file_name_no_ext+".spec")
    if remove:
        remove_file_name=entry_file_name_no_ext+(".exe" if platform.system()=="Windows" else "" if platform.system()=="Linux" else warnings.warn("系统无法识别"))
        remove_dir=entry_file_name_no_ext
        removeFolders([os.path.join("build",remove_file_name),os.path.join("dist",remove_dir)])
    if spec:
        if os.path.exists(spec_file):
            run(re.split(r"[ ]+",spec_file))
        else:
            warnings.warn(spec_file+"文件不存在，无法打包")
    else:
        cmd="-F %s -p %s"%(entry_file,nowpath)
        if len(add_data)>0:
            cmd="%s --add-data %s"%(cmd,add_data)
        for hidden_import_item in hidden_import:
            cmd="%s --hidden-import %s"%(cmd,hidden_import_item)
        run(re.split(r"[ ]+",cmd))

if __name__=="__main__":
    # add_data_from_path=os.path.join("multiagent","scenarios","*")
    # add_data_to_path=os.path.join("multiagent","scenarios")
    # to_marker=";" if platform.system()=="Windows" else ":" if platform.system()=="Linux" else warnings.warn("系统无法识别")
    # add_data="%s%s%s"%(add_data_from_path,to_marker,add_data_to_path)

    # add_res_from_path=os.path.join("res","*")
    # add_res_to_path=os.path.join("res")
    # to_marker=";" if platform.system()=="Windows" else ":" if platform.system()=="Linux" else warnings.warn("系统无法识别")
    # add_res="%s%s%s"%(add_res_from_path,to_marker,add_res_to_path)

    # hidden_import=file_walk_through(os.path.join("multiagent","scenarios"),".py")
    # doPackFun(os.path.join("bin","main_eval_mini.py"),add_data=add_res ,spec=False,remove=True)
    # doPackFun(os.path.join("bin","github_crawler.py"),add_data=add_res ,spec=False,remove=True)
    doPackFun(os.path.join("bin","github_crawler.py"))